package com.ssy.lingxi.platform.manage.serviceimpl;

import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.api.model.dto.secret.CheckPasswordDTO;
import com.ssy.lingxi.platform.manage.api.model.vo.secret.SecretKeyVO;
import com.ssy.lingxi.platform.manage.entity.base.SecretKey;
import com.ssy.lingxi.platform.manage.repository.SecretKeyRepository;
import com.ssy.lingxi.platform.manage.service.SecretKeyService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.security.SecureRandom;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

/**
 * 采购需求单密钥管理
 */
@Service
public class SecretKeyServiceImpl  implements SecretKeyService {
    
    @Resource
    SecretKeyRepository secretKeyRepository;

    /**
     * 查询秘钥
     */
    @Transactional
    @Override
    public Wrapper<SecretKeyVO> getSecretKey(UserLoginCacheDTO sysUser) {
        SecretKeyVO response=new SecretKeyVO();
        SecretKey secretKey = secretKeyRepository.findByMemberIdAndMemberRoleId(sysUser.getMemberId(), sysUser.getMemberRoleId());
        if(ObjectUtils.isEmpty(secretKey)||System.currentTimeMillis()>secretKey.getEffectiveTime()){
            secretKeyRepository.deleteAllByMemberIdAndMemberRoleId(sysUser.getMemberId(), sysUser.getMemberRoleId());
            secretKey=new SecretKey();
            secretKey.setMemberId(sysUser.getMemberId());
            secretKey.setMemberRoleId(sysUser.getMemberRoleId());
            secretKey.setMemberName(sysUser.getMemberRoleName());
            secretKey.setEffectiveTime(getTime());
            secretKey.setSecretKey(getGUID());
            secretKeyRepository.saveAndFlush(secretKey);
        }
        BeanUtils.copyProperties(secretKey,response);
        return Wrapper.success(response);
    }

    /**
     * 校验秘钥是否正确
     */
    @Override
    public Wrapper<Boolean> checkPassword(CheckPasswordDTO request) {
        SecretKey secretKey = secretKeyRepository.findByMemberIdAndMemberRoleId(request.getMemberId(), request.getMemberRoleId());
        if(ObjectUtils.isEmpty(secretKey)){
          return  Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        if(System.currentTimeMillis()>secretKey.getEffectiveTime()){
            secretKey.setEffectiveTime(getTime());
            secretKey.setSecretKey(getGUID());
            secretKeyRepository.saveAndFlush(secretKey);
            return Wrapper.fail(ResponseCode.SECRET_KEY_BE_OVERDUE);
        }
        if(!secretKey.getSecretKey().equals(request.getPassword())){
            return  Wrapper.fail(ResponseCode.SECRET_KEY_CHECK_NOT_ADOPT);
        }
        return  Wrapper.success(true);
    }

    /**
     * 获取7天后的时间戳
     */
    private Long  getTime(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 7);
        Date today = calendar.getTime();
        return today.getTime();
    }

    /**
     * 生成10位不重复的随机数，含数字+大小写
     */
    public static String getGUID() {
        StringBuilder uid = new StringBuilder();
        //产生16位的强随机数
        Random rd = new SecureRandom();
        for (int i = 0; i < 10; i++) {
            //产生0-2的3位随机数
            int type = rd.nextInt(3);
            switch (type){
                case 0:
                    //0-9的随机数
                    uid.append(rd.nextInt(10));
                    break;
                case 1:
                    //ASCII在65-90之间为大写,获取大写随机
                    uid.append((char)(rd.nextInt(25)+65));
                    break;
                case 2:
                    //ASCII在97-122之间为小写，获取小写随机
                    uid.append((char)(rd.nextInt(25)+97));
                    break;
                default:
                    break;
            }
        }
        return uid.toString();
    }
}
